// CSE 532 Lab 2 Fall 2006 Provided Code: Socket Output Iterator
// Authors: Venkita Subramonian and Chris Gill

#include <iostream>
#include <iterator>
#include "ace/SOCK_Stream.h"
#include "ace/Log_Msg.h"

#include "globals.h"

using namespace std;

template <typename T>
class osock_stream_iterator {

protected:

  // The ACE socket that acts as a container for the iterator
  ACE_SOCK_Stream* sock_stream_;

public:

  // Traits for the iterator
  typedef output_iterator_tag iterator_category;
  typedef void                value_type;
  typedef void                difference_type;
  typedef void                pointer;
  typedef void                reference;

  // Default constructor
  osock_stream_iterator(ACE_SOCK_Stream& s) : sock_stream_ (&s) {}

  // Assignment operator
  osock_stream_iterator<T>& operator=(const T& value) { 

    // This is a blocking write, which should be decoupled from
    // the current thread of execution, either by handing it off to an
    // active object that can perform the blocking write in its own
    // thread of execution, or by handing off the data to an object with
    // reactive concurrency (in a separate reactor thread from the thread
    // that calls this operator) that (1) stores a pointer to the
    // info to be transmitted (for example treating the parameterized
    // variable type as though it were a character array), (2)
    // maintains a pointer that marks how many bytes of the buffer have been
    // transmitted so far, and (3) updates the progress pointer each time
    // it's called, until there is no more data to send.

    int result = sock_stream_->send_n (&value, sizeof (T));
    if (DEBUG) std::cout << "Sent " << result << " bytes " << value << std::endl;
    if (result <= 0)
      cout << "Error: send result was " << result << endl;

    return *this;
  }

  // Pointer dereference operator
  osock_stream_iterator<T>& operator*() { return *this; }

  // Prefix increment operator
  osock_stream_iterator<T>& operator++() { return *this; } 

  // Postfix increment operator
  osock_stream_iterator<T>& operator++(int) { return *this; } 
};
